import React, { useState, useCallback, useEffect } from 'react'
import './App.css'
import AddInput from './components/AddInput';
import MyHeader from './components/Header'
import TodoItem from './components/TodoItem'
import CheckModal from './components/Modal/CheckModal';
import EditModal from './components/Modal/EditModal';
import NoDataTip from './components/NoDataTip';

function App() {

    const [isInputShow, setInputShow] = useState(false),
        [todoList, setTodoList] = useState([]),
        [isShowCheckModal, setShowCheckModal] = useState(false),
        // currentData 当点击查看按钮（openCheckModal）时，会通过setCurrentData()把传递的值给currentData
        [currentData, setCurrentData] = useState({}),
        [isShowEditModal, setShowEditModal] = useState(false);

    // useEffect副作用 多个useEffect是有执行顺序的
    // 进入-->获取本地数据todoList或者数据为空设置为localStorage的数据，然后解析成JOSN格式赋值给todoData
    // todoData：	[{"id":1644474390114,"content":"123","completed":false}]
    useEffect(() => {
        const todoData = JSON.parse(localStorage.getItem('todoList') || '[]')
        setTodoList(todoData)
    }, []);

    // 此时的useEffect依赖todoList的数据，一旦todoList中有新增数据便会执行此处的useEffect
    useEffect(() => {
        // todoList更新后 转化为字符串 并传给todoData
        localStorage.setItem('todoData', JSON.stringify(todoList))
    }, [todoList])

    // addItem 增加代事项
    // 父组件里定义的事件处理函数 作为参数传给子组件需要使用 useCallback包裹一下
    const addItem = useCallback((value) => {
        const dataItem = {
            id: new Date().getTime(),
            content: value,
            completed: false
        };
        // 重置数据列表，把输入框的数据传递给todoList
        setTodoList((todoList) => [...todoList, dataItem]);
        setInputShow(false);
    }, [])

    const removeItem = ((id) => {
        setTodoList((todoList) => todoList.filter((item) => item.id !== id))
    })

    // 对checkBox处理 点击 取反
    const completeItem = ((id) => {
        setTodoList((todoList) => todoList.map((item) => {
            if (item.id === id) {
                item.completed = !item.completed;
            }
            return item;
        }));
    })

    // 查看-按钮 点击该按钮时，会获取item.id 然后根据id使用filter获取todoList中的数据，因为filter返回的时一个数组，取第一项，然后赋值给currentData
    const openCheckModal = (
        (id) => {
            setCurrentData(() => todoList.filter((item) => item.id === id)[0])
            setShowCheckModal(true)
        }
    )

    const openEditModal = (
        (id) => {
            setCurrentData(() => todoList.filter((item) => item.id === id)[0]);
            setShowEditModal(true);
        }
    );

    const submitEdit = (
        (newData, id) => {
            setTodoList((todoList) =>
                todoList.map((item) => {
                    if (item.id === id) {
                        item = newData;
                    }
                    return item;
                })
            );
            setShowEditModal(false);
        }
    );


    return (
        <div className="App">
            <CheckModal
                isShowCheckModal={isShowCheckModal}
                data={currentData}
                closeModal={() => setShowCheckModal(false)}
            />
            <EditModal
                isShowEditModal={isShowEditModal}
                data={currentData}
                submitEdit={submitEdit}
            />
            <MyHeader openInput={() => setInputShow(!isInputShow)} />
            <AddInput
                isInputShow={isInputShow}
                addItem={(value) => addItem(value)}
            />
            {!todoList || todoList.length === 0 ? (
                <NoDataTip />
            ) : (
                <ul className="todo-list">
                    {todoList.map((item, index) => {
                        return (
                            <TodoItem
                                dataItem={item}
                                key={index}
                                removeItem={removeItem}
                                openCheckModal={openCheckModal}
                                completeItem={completeItem}
                                openEditModal={openEditModal}
                            />
                        );
                    })}
                </ul>
            )}
        </div>
    );
}

export default App;
